%{
#include "tokens.h"
#include "Tetr.h"
%}

%option noyywrap

Whitespace [ \t\v]+

Letter [a-z]

Digit [0-9]
NonZeroDigit [1-9]
PositiveInteger {NonZeroDigit}{Digit}*
IntegerLiteral "0"|{PositiveInteger}
FloatLiteral {IntegerLiteral}"."{Digit}*
CI {IntegerLiteral}
CF {FloatLiteral}
CB "true"|"false"

TypeBase "int"|"float"|"bool"

Ident {Letter}({Letter}|{Digit})*

AssignOperator "+="|"-="|"*="|"/="|"="
AddOperator [-+]
MultOperator [*/]
Relation [<>]|"=="|"!="|"<="|">="
UnaryOperator "++"|"--"|"-"|"~"

Operator {AssignOperator}|{AddOperator}|{MultOperator}|{Relation}|{UnaryOperator}

Separator [{}();,:?]|"["|"]"

Cout "cout"{Whitespace}?"<<"
Cin "cin"{Whitespace}?">>"

%%

{Whitespace}

"if"     { return IF;}
"else"   { return ELSE;}
"main"   { return MAIN;}
"void"   { return VOID;}
"for"    { return FOR;}
"goto"   { return GOTO;}
{Cout}   { return COUT;}
{Cin}    { return CIN;}
"or"     { return OR;}
"and"    { return AND;}
"not"    { return NOT;}
"vector" { return VECTOR;}
"~"      { return VSIZE_OPERATOR;}

{TypeBase} {keyword(yytext); return TYPE_BASE;}

{Separator} { separator(yytext); return *yytext;}
{CI} { yylval = integerConst(yytext); return INTEGER; }
{CF} { yylval = floatingConst(yytext); return FLOAT; }
{CB} { keyword(yytext); return BOOL; }

{Ident} { identifier(yytext); return IDENTIFIER; }

{AssignOperator} {oper(yytext); return ASSIGN_OPERATOR;}
{AddOperator}    {oper(yytext); return ADD_OPERATOR;}
{MultOperator}   {oper(yytext); return MULT_OPERATOR;}
{Relation}       {oper(yytext); return RELATION;}
{UnaryOperator}  {oper(yytext); return UNARY_OPERATOR;}

%%
#ifdef DEBUG_FLEX
void assignOperator(const char *p)
{
  printf("AssignOperator: %s\n", p);
}

void addOperator(const char *p)
{
  printf("AddOperator: %s\n", p);
}

void multOperator(const char *p)
{
  printf("MultOperator: %s\n", p);
}

void relation(const char *p)
{
  printf("Relation: %s\n", p);
}

void unaryOperator(const char *p)
{
  printf("UnaryOperator: %s\n", p);
}

void typeBase(const char *p)
{
  printf("type: %s\n", p);
}

void keyword(const char *p)
{
  printf("keyword: %s\n", p);
}

void separator(const char *p)
{
  printf("separator: %s\n",p);
}

int integerConst(const char *p)
{
  printf("integerConst: %s\n",p);
  return 0;
}

int floatingConst(const char *p)
{
  printf("floatingConst: %s\n",p);
  return 0;
}

int boolConst(const char *p)
{
  printf("boolConst: %s\n", p);
  return 0;
}

int identifier(const char *p)
{
  printf("identifier: %s\n",p);
  return 0;
}

void oper(const char *p)
{
  printf("operator: %s\n",p);
}

int yyerror(const char *p)
{
  printf("%s\n",p);
  return 0;
}

#endif